﻿using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Xml.Serialization;
using System.Globalization;
namespace FTchina.Library
{
    public class SerializationHelper
    {
        private SerializationHelper()
        {
        }
        /// <summary>
        /// 序列化成XML
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string SerializeToXml(Object obj)
        {
            try
            {
                if (obj == null)
                {
                    return "";
                }
                Type type = obj.GetType();
                string text;
                XmlSerializer serializer = new XmlSerializer(type);
                using (StringWriter writer = new StringWriter(CultureInfo.CurrentCulture))
                {
                    serializer.Serialize(writer, obj);
                    text = writer.ToString();
                }
                return text;
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(ex.ToString());
                return "";
            }
        }
        /// <summary>
        /// 序列化成XML文件
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static bool SerializeToXmlFile(Object obj, string fileName)
        {
            bool result = false;
            try
            {
                if (obj == null)
                {
                    return result;
                }
                Type type = obj.GetType();
                //    fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
                XmlSerializer serializer = new XmlSerializer(type);
                using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
                {
                    serializer.Serialize(fs, obj);
                }
                result = true;
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(ex.ToString());
            }
            return result;
        }
        /// <summary>
        /// 序列化成Binary 字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string SerializeToBinary(Object obj)
        {
            try
            {
                if (obj == null)
                {
                    return "";
                }
                if (!IsSerializable(obj))
                {
                    return "";
                }
                BinaryFormatter serializer = new BinaryFormatter();
                using (MemoryStream ms = new MemoryStream())
                {
                    serializer.Serialize(ms, obj);
                    if (ms.Length != 0)
                    {
                        return Convert.ToBase64String(ms.ToArray());
                    }
                }
                return "";
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(ex.ToString());
                return "";
            }
        }
        /// <summary>
        /// 序列化Binary 为File
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static bool SerializeToBinaryFile(Object obj, string fileName)
        {
            bool result = false;
            try
            {
                if (obj == null)
                {
                    return result;
                }
                if (!IsSerializable(obj))
                {
                    return result;
                }
                BinaryFormatter serializer = new BinaryFormatter();
                using (FileStream fs = File.Create(fileName, 1024, FileOptions.WriteThrough))
                {
                    serializer.Serialize(fs, obj);
                }
                result = true;
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(ex.ToString());
            }
            return result;
        }
        /// <summary>
        /// 对象是否能序列化
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsSerializable(object obj)
        {
            if (obj == null)
            {
                return false;
            }
            Type type = obj.GetType();
            Type attributeType = typeof(SerializableAttribute);
            SerializableAttribute attribute = null;
            if (!(attributeType.IsSubclassOf(typeof(Attribute))))
            {
                return false;
            }
            if (type.IsDefined(attributeType, false))
            {
                object[] attributes = type.GetCustomAttributes(attributeType, false);
                if (attributes.Length > 0)
                {
                    attribute = (SerializableAttribute)attributes[0];
                }
            }
            if (attribute != null)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 从xml字符串反序列化
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static object DeserializeFromXml(string xml, Type type)
        {
            try
            {
                if (String.IsNullOrEmpty(xml))
                {
                    return null;
                }
                XmlSerializer deserializer = new XmlSerializer(type);
                using (StringReader reader = new StringReader(xml))
                {
                    object obj = deserializer.Deserialize(reader);
                    return obj;
                }
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(ex.ToString());
                return null;
            }
        }
        public static object DeserializeFromXmlFile(string fileName, Type type)
        {
            try
            {
                if (String.IsNullOrEmpty(fileName) || !File.Exists(fileName))
                {
                    return null;
                }
                XmlSerializer deserializer = new XmlSerializer(type);
                using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    object obj = deserializer.Deserialize(fs);
                    return obj;
                }
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(ex.ToString());
                return null;
            }
        }
        /// <summary>
        /// 从base64字符串反序列
        /// </summary>
        /// <param name="hexValue"></param>
        /// <returns></returns>
        public static object DeserializeFromBinary(string base64Str)
        {
            try
            {
                if (String.IsNullOrEmpty(base64Str))
                {
                    return null;
                }
                BinaryFormatter deserializer = new BinaryFormatter();
                byte[] data = Convert.FromBase64String(base64Str);
                if ((data != null) && (data.Length > 0))
                {
                    MemoryStream ms = new MemoryStream(data);
                    return deserializer.Deserialize(ms);
                }
                return null;
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(ex.ToString());
                return null;
            }
        }
        /// <summary>
        /// 从文件反序列
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static object DeserializeFromBinaryFile(string fileName)
        {
            try
            {
                if (String.IsNullOrEmpty(fileName) || !File.Exists(fileName))
                {
                    return null;
                }
                BinaryFormatter deserializer = new BinaryFormatter();
                using (FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Delete))
                {
                    return deserializer.Deserialize(fs);
                }
                //return null;
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(ex.ToString());
                return null;
            }
        }
    }
}

